package com.jy.modules.cims.interact;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.CimsIrtUrlConstant;
import com.jy.modules.cims.common.sysUtils.CollectionsUtils;
import com.jy.modules.cims.common.sysUtils.PropertyUtil;
import com.jy.modules.cims.common.sysUtils.SearchParamUtil;
import com.jy.modules.cims.data.dao.EsbInterDao;
import com.jy.modules.cims.data.dto.ApproveConfirmResultDto;
import com.jy.modules.cims.data.dto.ConfirmParamDto;
import com.jy.modules.cims.data.interact.xintian.ResponseMessage;
import com.jy.modules.cims.data.interact.xintian.Root;
import com.jy.modules.cims.data.interact.xintian.error.EsbHead;
import com.jy.modules.cims.data.interact.xintian.loanDetail.ImageInfo;
import com.jy.modules.cims.data.interact.xintian.loanDetail.LoanInfo;
import com.jy.modules.cims.data.interact.xintian.loanDetail.OrgLoanTotal;
import com.jy.modules.cims.data.interact.xintian.loanDetail.ReturnMessage;
import com.jy.modules.cims.data.interact.xintian.loanresult.request.LoanBatch;
import com.jy.modules.cims.data.interact.xintian.loanresult.request.LoanReq;
import com.jy.modules.cims.data.interact.xintian.loanresult.request.OrgLoanStatusRequest;
import com.jy.modules.cims.data.interact.xintian.loanresult.response.LoanStatus;
import com.jy.modules.cims.data.interact.xintian.loanresult.response.OrgLoanStatusResponse;
import com.jy.modules.cims.data.interact.xintian.loanresult.response.ResHead;
import com.jy.modules.cims.interact.common.InteractConstant;
import com.jy.modules.cims.interact.util.XmlConvertUtil;
import com.jy.modules.platform.sysdict.impl.SysDictAPImpl;
import com.jy.platform.core.message.DataMsg;
import com.jy.platform.core.message.PageParameter;
import com.jy.platform.core.message.PageUtil;
import com.jy.platform.core.message.QueryReqBean;
import com.thoughtworks.xstream.mapper.CannotResolveClassException;

/**
 * 
 * @classname: CInteractExternalmplNew
 * @description: 新天贷款发送审核，查询结果实现类
 */
@Service("com.jy.modules.cims.interact.CInteractExternalmplNew")
public class CInteractExternalmplNew extends AbstractInteractExternal {

    @Autowired
    private EsbInterDao esbInterDao;

    @Autowired
    @Qualifier("com.jy.modules.cims.interact.CCInteractImpl")
    private ICInteract cInteract;

    @Autowired
    @Qualifier("com.jy.modules.cims.interact.CInteractAssist")
    private IInteractAssist iInteractAssist;

    @Autowired
    @Qualifier("com.jy.modules.cims.interact.InteractClassInvokeService")
    private InteractClassInvokeService interactClassInvokeService;

    @Autowired
    private SysDictAPImpl sysDictAPI;

    /*
     * 
     */
    private static final Logger logger = LoggerFactory.getLogger(CInteractExternalmplNew.class);

    /*
     * 发送贷款明细接口地址.
     */
    private static final String SEND_URL = PropertyUtil.get(InteractConstant.XINTIAN_SEND_URL);

    /*
     *查询贷款审核结果接口地址. 
     */
    private static final String QUERY_URL = PropertyUtil.get(InteractConstant.XINTIAN_QUERY_URL);

    /*
     * 发送贷款明细每个批次100条
     */
    static int pageSize = 100;

    /**
     * 发送。。。。。 根据交易流水号，查询改流水号下所有贷款明细 发送，
     * 发送loan_each_status=03的贷款明细，成功返回ReturnMessage， 更新状态为04，记录批次表。
     */
    public void sendLoanInfos() {
        logger.info("发送贷款明细申请开始！");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String date = sdf.format(new Date());
        List<Map<String, String>> dealCodeList = esbInterDao.selectLoanInfo();
        logger.info("发送贷款明细申请，共" + dealCodeList.size() + "个交易流水号！");
        for (Map<String, String> map : dealCodeList) {
            // 一个交易了流水号下，按每次发送一百条发送，每一百条更新发送成功状态
            writeLoanInfoStatus(map, date);
        }
        logger.info("发送贷款明细申请结束！");
    }

    /**
     * 发送贷款明细成功后，更新贷款明细状态，记录发送批次表
     * 
     * @title: updateLoanInfoStatus
     * @author
     * @description:
     * @date 2015-2-12 上午9:51:32
     * @param sendList 发送成功的贷款明细
     * @throws
     */
    public void writeLoanInfoStatus(Map<String, String> map, String date) {
        Map<String, Object> searchParams = new HashMap<String, Object>();
        LoanInfo l = new LoanInfo();
        String deal_code = map.get("DEALCODE").toString();
        l.setLoanNo(deal_code);
        searchParams.put("dto", l);
        QueryReqBean params = new QueryReqBean();
        params.setSearchParams(searchParams);
        DataMsg dataMsg = new DataMsg();
        dataMsg.setPageSize(pageSize);
        PageParameter pageInfo = PageUtil.toPageParameter(dataMsg);
        params.setPageParameter(pageInfo);
        // 查询状态是03的贷款明细,分批次发送
        int total = esbInterDao.selectLoanInfoCount(deal_code);
        int batch = 0;
        if (total % pageSize > 0) {
            batch = total / pageSize + 1;
        } else if (total % pageSize == 0) {
            batch = total / pageSize;
        }

        // 根据贷款交易流水号查询是否已经生成批次号？生成批次号batchNo
        String ID = String.valueOf(esbInterDao.selectBatchIdStr());
        // 批次号19位// 批次号
        int batchNoint = esbInterDao.selectBatchNoStr();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String batchNoStr = sdf.format(new Date()) + String.format("%011d", batchNoint);
        Map<String, String> batchMap = new HashMap<String, String>();
        batchMap.put("deal_code", deal_code);
        batchMap.put("batch_no", batchNoStr);
        batchMap.put("id", ID);
        esbInterDao.insertBatchNo(batchMap);
        
        logger.info("生成批次号：" + batchNoStr + ",交易流水为：" + deal_code);
        // 贷款申请数据报送主键
        String batchNo = batchNoStr;
        for (int i = 0; i < batch; i++) {
            // 组织数据，汇总数据
            List<LoanInfo> sendList = esbInterDao.selectLoanInfoByPaging(params.getSearchParams());
            BigDecimal loanAmount = new BigDecimal("0");
            for (LoanInfo loanInfo : sendList) {
                loanAmount = loanAmount.add(loanInfo.getLoanMoney());
                loanInfo.setBatchNo(batchNo);
                loanInfo.setCustType(InteractConstant.XINTIAN_DATA_CUSTTYPE);// 测试
                loanInfo.setLoanWay(InteractConstant.XINTIAN_DATA_LOANWAY);// 测试
                loanInfo.setLoanCollectTypeName(InteractConstant.XINTIAN_DATA_LOANCOLLECTTYPENAME);
                loanInfo.setOrgNo(InteractConstant.XINTIAN_DATA_ORGNO);
                String code = loanInfo.getPersonInfo().getPersonSettle().getSettleBankCode();
                loanInfo.getPersonInfo()
                        .getPersonSettle()
                        .setSettleBankName(
                                sysDictAPI.queryDetailByDictCodeAndDeatailValue("BANKCODE", code).getDictDetailName());
                ArrayList<ImageInfo> ims = new ArrayList<ImageInfo>();
                ims.add(loanInfo.getImages().get(0));
                loanInfo.setImages(ims);
            }
            OrgLoanTotal orgLoanTotal = new OrgLoanTotal();
            orgLoanTotal.setID(ID);
            orgLoanTotal.setBatchNo(batchNo);
            orgLoanTotal.setLoans(sendList);
            orgLoanTotal.setLoanNum(sendList.size());
            orgLoanTotal.setLoanAmount(loanAmount.toString());
            orgLoanTotal.setSendDate(date);
            orgLoanTotal.setOrgNo(InteractConstant.XINTIAN_DATA_ORGNO);
            Root root = new Root();
            root.setOrgLoanTotal(orgLoanTotal);
            logger.info("第" + i + "次发送明细" + sendList.size());
            ResponseMessage res = (ResponseMessage) send(SEND_URL, root);
            if (res.getEsbHead() != null) {
                // 错误
                // break;
                logger.error("第" + i + "次发送明细失败：" + res.getEsbHead().getErrorinfo());
            } else {
            	logger.info("新天返回报文>>"+JSON.toJSONString(res));
                // 发送成功
                // 打标识表示发送成功；另外一个接口查询贷款申请是否成功，
                esbInterDao.updateLoanSendStatus(sendList);
                logger.info("第" + i + "次发送明细成功：" + res.getReturnMessage().getResponseDesc() + sendList.size());
            }
        }
    }

    /**
     * 查询审核结果
     * 
     * @throws Exception
     * @title: queryResult
     * @author
     * @description:
     * @date 2015-2-11 下午3:19:45
     * @throws
     */
    public void queryResult() throws Exception {
        logger.info("查询贷款审核结果开始！");
        List<LoanBatch> batchlist = esbInterDao.selectLoanBatch();
        logger.info("查询贷款审核结果，共" + batchlist.size() + "个批次号！");
        // 一个批次一次查询请求
        for (LoanBatch loanBatch : batchlist) {
            // 查询状态是04的,查询审核状态
            String batchNo = loanBatch.getBatchNo();
            List<LoanReq> sendList = esbInterDao.selectLoanReq(batchNo);
            logger.info("查询贷款审核结果批次号为：" + batchNo);
            Root root = new Root();
            OrgLoanStatusRequest orgLoanStatusRequest = new OrgLoanStatusRequest();
            root.setOrgLoanStatusRequest(orgLoanStatusRequest);
            orgLoanStatusRequest.setLoanBatch(loanBatch);
            orgLoanStatusRequest.setLoanReqs(sendList);
            ResponseMessage res = (ResponseMessage) query(QUERY_URL, root);
            if (res.getEsbHead() != null) {
                // 错误。如何处理？
                logger.error("查询贷款审核结果错误：" + res.getEsbHead().getErrorcode() + "-" + res.getEsbHead().getErrorinfo());
            } else {
                OrgLoanStatusResponse orgLoanStatusResponse = res.getOrgLoanStatusResponse();
                String responseCode = orgLoanStatusResponse.getResHead().getResponseCode();
              
                // 查询成功,
                if (InteractConstant.XINTIAN_SUCCESS.equals(responseCode)) {
                	List<LoanStatus> newList = new ArrayList<LoanStatus>();
                    List<LoanStatus> responseList = orgLoanStatusResponse.getResBody();
                    if(CollectionsUtils.isNotEmpty(responseList)){
                    	for(LoanStatus temp:responseList){
                            if ("1".equals(temp.getResult())) {
                                temp.setResult(CimsConstant.LOAN_CONFIRM_WIN);
                                newList.add(temp);
                            } else if ("2".equals(temp.getResult())) {
                                temp.setResult(CimsConstant.LOAN_CONFIRM_LOSE);
                                newList.add(temp);
                            }
                    	}
                    	
                        // 一个批次一次查询请求，成功后，更新状态
                        updateLoanResult(newList);
                    }
                    logger.info("查询贷款审核结果成功：" + res.getOrgLoanStatusResponse().getResHead().getResponseDesc()
                            + ",更新贷款明细：" + (newList == null ? 0 : newList.size()) + "条");
                } else {
                    // 查询失败处理？
                    logger.error("查询贷款审核结果失败：" + orgLoanStatusResponse.getResHead().getResponseCode() + "-"
                            + orgLoanStatusResponse.getResHead().getResponseDesc());
                }
            }
        }
        logger.info("查询贷款审核结果结束！");
    }

    /**
     * 查询审核结果后，更新标识：01审核通过，02审核未通过
     * 
     * @title: updateLoanResult
     * @author
     * @description:
     * @date 2015-2-13 下午3:07:21
     * @param responseList
     * @throws Exception
     * @throws
     */
    public void updateLoanResult(List<LoanStatus> responseList) throws Exception {
        if (responseList != null && !responseList.isEmpty()) {
            for (LoanStatus loanStatus : responseList) {
                // List<LoanStatus> list
                esbInterDao.updateLoanStatus(SearchParamUtil.getSearchParam(loanStatus));
            }
        }
    }

    public ApproveConfirmResultDto approveConfirm(ConfirmParamDto approveDto) {
        return cInteract.approveConfrim(approveDto);
    }

    @Override
    public String sendBefore(Object root) {
        return XmlConvertUtil.convertDTO2Str((Root) root);
    }

    @Override
    public Object sendAfter(String str) {
        Root temple = new Root();
        ReturnMessage returnMessage = new ReturnMessage();
        temple.setReturnMessage(returnMessage);

        ReturnMessage retMes = null;
        EsbHead esbHead = null;
        try {
            retMes = XmlConvertUtil.convertStr2DTO(str, temple).getReturnMessage();
        }
        catch (CannotResolveClassException e) {
            esbHead = XmlConvertUtil.convertStr2Error(str).getEsbhead();
        }
        return new ResponseMessage(esbHead, retMes);
    }

    @Override
    public String qeuryBefore(Object root) {
        return XmlConvertUtil.convertDTO2Str((Root) root);
    }

    @Override
    public Object queryAfter(String str) {
        // str =
        // "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Root><orgLoanStatusResponse><resHead><responseCode>20001</responseCode><responseDesc>调用贷款审核状态查询接口成功</responseDesc><responseDate>2014-09-05 11:32:25.134</responseDate></resHead><resBody><loanStatus><loanId>1</loanId><loanNo>xxx1</loanNo><result>1</result><desc>贷款申请已通过审核</desc><processTime>2014-09-05 10:22:12</processTime></loanStatus><loanStatus><loanId>2</loanId><loanNo>xxx2</loanNo><result>2</result><desc>缺少贷款合同影印件</desc><processTime>2014-09-05 10:23:32</processTime></loanStatus><loanStatus><loanId>3</loanId><loanNo>xxx3</loanNo><result>0</result> </loanStatus></resBody></orgLoanStatusResponse></Root>";
        Root temple = new Root();
        OrgLoanStatusResponse orgLoanStatusResponse = new OrgLoanStatusResponse();
        temple.setOrgLoanStatusResponse(orgLoanStatusResponse);
        ResHead resHead = new ResHead();
        LoanStatus loanStatus = new LoanStatus();
        List<LoanStatus> loanStatusList = new ArrayList<LoanStatus>();
        loanStatusList.add(loanStatus);
        orgLoanStatusResponse.setResBody(loanStatusList);
        orgLoanStatusResponse.setResHead(resHead);
        EsbHead esbHead = null;
        OrgLoanStatusResponse orgLoanStatusRes = null;
        try {
            orgLoanStatusRes = XmlConvertUtil.convertStr2DTO(str, temple).getOrgLoanStatusResponse();
        }
        catch (Exception e) {
            esbHead = XmlConvertUtil.convertStr2Error(str).getEsbhead();
        }
        return new ResponseMessage(esbHead, orgLoanStatusRes);
    }

    /**
     * 核心接口
     * 
     * @title: testUpdateResult
     * @author
     * @description:
     * @date 2015-3-4 下午4:07:00
     * @throws
     */
    public void aproveResult() {
        logger.info("发送核心贷款审批确认开始！");
        List<LoanStatus> responseList = esbInterDao.approveResult();
        if (responseList != null && !responseList.isEmpty()) {
            ConfirmParamDto approveDto = new ConfirmParamDto();
            List<ConfirmParamDto.LoanApproveInfo> approveList = new ArrayList<ConfirmParamDto.LoanApproveInfo>();
            for (LoanStatus loanStatus : responseList) {
                ConfirmParamDto.LoanApproveInfo loanApproveInfo = approveDto.new LoanApproveInfo();
                loanApproveInfo.setContractNo(loanStatus.getLoanNo());
                String type = loanStatus.getResult();
                loanApproveInfo.setApproveType("02".equals(type) ? CimsIrtUrlConstant.IRT_LOAN_APPROVE_SUCCESS
                        : CimsIrtUrlConstant.IRT_LOAN_APPROVE_FAIL);
                loanApproveInfo.setApproveReason(loanStatus.getDesc());
                approveList.add(loanApproveInfo);
            }
            approveDto.setApproveList(approveList);
            String busiNoForInteract = iInteractAssist.getInteractNo();
            approveDto.setBusiType(CimsConstant.QUOTATYPE_LOAN);// 业务类型
            approveDto.setDealCode(busiNoForInteract);// 交易流水
            iInteractAssist.registerDealIrtService(busiNoForInteract);
            interactClassInvokeService.saveInteractClassInvoke(busiNoForInteract, this.getClass(), "approveConfirm",
                    approveDto);
            ApproveConfirmResultDto approveConfirmResultDto = approveConfirm(approveDto);
            // 确认成功再更新状态
            if (approveConfirmResultDto != null)
                esbInterDao.updateApproveResult(responseList);
            logger.info("发送核心贷款审批确认结束！");
        }
    }

}
